home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Technotools
/
Technotools (Chestnut CD-ROM)(1993).ISO
/
lang_c
/
mscheap2
/
bench.c
next >
Wrap
C/C++ Source or Header
|
1990-03-13
|
5KB
|
226 lines
//
// Copyright (c) 1990 by Optimal Software, All Rights Reserved
//
//
// This program is a simple benchmark for heap management
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <heap.h>
//
// Declare globals so that linking with original heap manager does not
// produce undefined symbols.
//
int _heapmode;
size_t _heappad ;
static void exercise( long iterations );
/******************************************************************************/
//
// Exercise the heap manager
//
int main( int argc, char *argv[] )
{
switch( argc )
{
case 4: _heappad = atoi( argv[3] ); /* 'ware fall through */
case 3: _heapmode = atoi( argv[2] ); /* 'ware fall through */
case 2: exercise( atol( argv[1] ) );
break;
default: fprintf( stderr, "Usage: bench iteration_count [heapmode] [heappad]\n" );
}
return( 0 );
}
/******************************************************************************/
static void exercise( long iterations )
{
typedef struct block
{
struct block far *next;
struct block far *last;
} BLOCK;
int status;
long count=iterations, fails=0;
time_t seconds = time(NULL);
BLOCK far *tmp, far *list = _fmalloc( sizeof(BLOCK) );
list->next = list;
list->last = list;
srand(12345);
while (count--)
{
int skew, todo;
size_t size = sizeof(BLOCK);
/*/
Mimic the natural emphasis on small chunks by generating an offset
with a triangular distribution. The difference of randoms creates
a square of results with zeros on the diagonal. Suppressing the
negative values leaves a triangle with 32768 zeros on the diagonal,
a single 32767 in the corner, and a range of intermediate values.
Every value {N:0..32767} appears 32768-N times.
/*/
do
{
skew = rand() - rand();
}
while (skew < 0);
size += rand() % (uint) (skew+1);
todo = rand() % 6; /* 3 parts malloc (more than free so heap grows)
2 parts free
1 part realloc (also tests _expand) */
if (list->next == list)
todo = 0; /* list is empty, malloc something! */
switch( todo )
{
case 0 : /* malloc */
case 1 :
case 2 : tmp = (BLOCK far *) _fmalloc(size);
if (tmp != NULL)
{
tmp->next = list->next; /* insert new item in list */
tmp->last = list;
tmp->next->last = tmp;
tmp->last->next = tmp;
}
else
fails++; /* oops, no room in heap */
break;
case 3: /* free */
case 4: tmp = list->next;
tmp->next->last = tmp->last; /* delete from list */
tmp->last->next = tmp->next;
_ffree(tmp);
break;
case 5: /* realloc */
tmp = list->next; /* pick a victim */
tmp->next->last = tmp->last; /* delete from list in case of failure */
tmp->last->next = tmp->next;
tmp = _hrealloc(tmp, (long) size ); /* change size and possibly address */
if (tmp != NULL)
{
tmp->next = list->next; /* insert back into list */
tmp->last = list;
tmp->next->last = tmp;
tmp->last->next = tmp;
}
else
fails++; /* oops */
break;
} /* switch */
//
// Move around in the list to avoid emulating a stack.
//
list = list->next;
}
seconds = time(NULL) - seconds;
if ( (status = _fheapset(-1) ) != _HEAPOK)
printf("Heap error: %s\n", _heapstat( status ) );
else
{
// //
// // This code implements an MSC-compatible heap inspection using
// // _heapwalk() to traverse the heap entries.
// //
// struct _heapinfo hp;
//
// int status;
//
// hp._pentry = NULL;
//
// while ( (status = _fheapwalk( &hp ) ) == _HEAPOK)
//
// printf("%5u at %Fp %s\n",
// hp._size,
// hp._pentry,
// hp._useflag ? "" : "free" );
//
// Announce results
//
printf("\n%ld iterations, %ld failures, %ld seconds\n\n",
iterations,
fails,
seconds );
// //
// // This code implements a clean-up operation that is necessary if
// // the exercise function is to be called more than once. As the
// // current implementation uses only one pass, this code is unnecessary.
// //
// // Note: there is no MSC version of heapdump().
// //
// printf("Final heap state\n\n");
//
// _heapdump( stdout, TRUE );
//
// while (list->next != list)
// {
// BLOCK far *tmp = list->next;
//
// tmp->next->last = tmp->last;
// tmp->last->next = tmp->next;
//
// free(tmp);
// }
//
// free(list);
//
// _heappack();
//
// printf("Post-cleanup heap state\n\n");
//
// _heapdump( stdout, TRUE );
}
}
/******************************************************************************/